﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Compression;

namespace Logger
{
    class Gl
    {
       public static string dPathScreen;
       public static string fPathSettings;

       public static Settings sett;
    }

    public class Settings
    {
        public int PartsLen = 2000; // количество сегментов, на которые бьется картинка
        public bool HalfSise = false;
        public int BufLen = 40; // размер буфера в кадрах
        public bool DEBUG_MODE = false;
        public int HistDaysLen = 3;

        public Settings()
        {
            if (File.Exists(Gl.fPathSettings))
            {
                String[] strl = File.ReadAllLines(Gl.fPathSettings, Encoding.UTF8);
                for (int i = 0; i < strl.Length; i++)
                {
                    string[] sl = strl[i].Split(new Char[1] { '=' }, 2);
                    if (sl.Length < 2) continue;
                    string key = sl[0].Trim();
                    string val = sl[1].Trim();

                    if (key == "PartsLen") { int tmpInt; if (int.TryParse(val, out tmpInt)) PartsLen = tmpInt; }
                    if (key == "HalfSise") HalfSise = val == "1";
                    if (key == "BufLen") { int tmpInt; if (int.TryParse(val, out tmpInt)) BufLen = tmpInt; }
                    if (key == "DEBUG_MODE") DEBUG_MODE = val == "1";
                    if (key == "HistDaysLen") { int tmpInt; if (int.TryParse(val, out tmpInt)) if (tmpInt > 0) HistDaysLen = tmpInt; }
                }
            }
        }

        public void Save()
        {
            List<string> strL = new List<string>();
            strL.Add("PartsLen = " + PartsLen.ToString());
            strL.Add("HalfSise = " + (HalfSise ? "1" : "0"));
            strL.Add("BufLen = " + BufLen.ToString());
            strL.Add("DEBUG_MODE = " + (DEBUG_MODE ? "1" : "0"));
            strL.Add("HistDaysLen = " + HistDaysLen.ToString());
           
            File.WriteAllLines(Gl.fPathSettings, strL.ToArray(), Encoding.UTF8);
        }
    }

    class ScreenData
    {
        public static int PartsLen = 2000;

        public DateTime dt;
        public byte[] ind = new byte[PartsLen]; // массив индексов частей (от какого элемента какую часть брать) (не сохраняется. Сделано только для скорости)
        public Part[] prtL; // массив частей
        // размер одной части
        public readonly int lenPart;
        public readonly int lenLastPart;
        public int w;
        public int h;
        // размер последней части
        public ScreenData(Part[] prtL, byte[] ind, int lenPart, int lenLastPart, int w, int h, DateTime dt)
        {
            this.dt = dt;
            this.w = w;
            this.h = h;
            this.prtL = prtL;
            this.ind = ind;
            this.lenPart = lenPart;
            this.lenLastPart = lenLastPart;
        }

        public byte[] GetActPart(int indPart, List<ScreenData> scrL)
        {
            return scrL[ind[indPart]].prtL[indPart].mas;
        }

        public byte[] GetScreen(List<ScreenData> scrL)
        {
            MemoryStream ms = new MemoryStream();
            BinaryWriter bw = new BinaryWriter(ms);
            for (int i = 0; i < PartsLen - 1; i++)
            {
                bw.Write(GetActPart(i, scrL));
            }
            bw.Close();
            byte[] ret = ms.ToArray();
            ms.Close();
            ms.Dispose();
           /* byte[] ret = new byte[0];
            for (int i = 0; i < PartsLen - 1; i++)
            {
                Array.Resize(ref ret, ret.Length + lenPart);
                Array.Copy(GetActPart(i, scrL), 0, ret, ret.Length - lenPart, lenPart);
            }
            Array.Resize(ref ret, ret.Length + lenLastPart);
            Array.Copy(GetActPart(PartsLen - 1, scrL), 0, ret, ret.Length - lenLastPart, lenLastPart);*/

            return ret;
        }

    }

    class Part
    {
        public byte[] mas = null;
        public Part() { }

        //public int this[int ind] { get { return mas[ind]; } }
    }

    class YCmpr
    {
        public static byte[] Compress(byte[] buf)
        {
            using (MemoryStream memoryStream = new MemoryStream())
            using (GZipStream zipStream = new GZipStream(memoryStream, CompressionMode.Compress, true))
            {
                zipStream.Write(buf, 0, buf.Length);
                zipStream.Close();
                return memoryStream.ToArray();
            }
        }

        public static byte[] Decompress(byte[] buf)
        {
            byte[] result = new byte[0];
            if ((buf != null) && (buf.Length != 0))
            {
                MemoryStream ms = new MemoryStream(buf);
                /*ms.Write(buf, 0, buf.Length);
                ms.Position = 0;*/
                using (GZipStream unzipStream = new GZipStream(ms, CompressionMode.Decompress))
                {
                    byte[] unzipBuffer = new byte[134217728];
                    bool first = true;
                    while (true)
                    {
                        int bytesRead = unzipStream.Read(unzipBuffer, 0, unzipBuffer.Length);
                        if (bytesRead == 0 && !first)
                            break;

                        first = false;

                        Array.Resize(ref result, result.Length + bytesRead);
                        Array.Copy(unzipBuffer, 0, result, result.Length - bytesRead, bytesRead);
                    }
                    GC.Collect();
                }
            }
            return result;
        }

        // ужать текст
        public static byte[] CompressText(String text)
        {
            return Compress(Encoding.Unicode.GetBytes(text));
        }

        public static String DecompressText(byte[] buf)
        {
            return Encoding.Unicode.GetString(Decompress(buf));
        }
    }
}
